package com.yuzhihao.writejvm.method;

import com.yuzhihao.writejvm.clazz.ClassInfo;
import com.yuzhihao.writejvm.format.ClassFormatEnum;
import com.yuzhihao.writejvm.read.Parse;
import lombok.Data;
import lombok.extern.log4j.Log4j2;

import java.io.DataInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * Each method, including each instance initialization method (§2.9) and the class or interface initialization method (§2.9), is described by a method_info structure.
 *
 * No two methods in one class file may have the same name and descriptor (§4.3.3).
 *
 * <a href="https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6">Methods</a>
 * @author yzh
 * @since 2021年12月12日17:49:30
 */
@Data
@Log4j2
public class Methods implements Parse {

    private ClassFormatEnum cfe_mc = ClassFormatEnum.methods_count;

    protected int count;

    protected ClassInfo ci;

    private List<MethodInfo> infos = new ArrayList<>();

    @Override
    public void parse(DataInputStream dis, ClassInfo ci) {
        try {
            this.count = Parse.byteToInt(cfe_mc.getB(), dis);
            this.out(ci);
            int i = 0;
            while (i < this.count){
                MethodInfo info = new MethodInfo();
                info.parse(dis, ci);
                infos.add(info);
                i++;
            }

        } catch (IOException e) {
            log.error(e);
        }
    }

    public void out(ClassInfo ci) {
        this.setCi(ci);
        ci.setMethods_count(this.count);
        ci.setMethod_info(this);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        for (MethodInfo info : infos) {
            builder.append(info.print(this.ci));
        }
        return builder.toString();
    }
}
